﻿using System;
using System.Net;
using System.Net.Sockets;

namespace OestsCommon.TcpNet
{
    public abstract class TcpClient
    {
        private Socket _worksocket;//当前套接字
        private Message _msg = new Message();

        /// <summary>
        /// 创建并尝试连接服务器
        /// </summary>
        /// <param name="ip">服务器地址</param>
        /// <param name="port">服务器端口</param>
        public bool TryConnect(string ip, int port)
        {
            IPAddress.TryParse(ip, out IPAddress ipAddress);
            _worksocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                _worksocket.Connect(ip, port);
                AsynRecive();
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine("错误： " + e.Message);
                return false;
            }
        }
        /// <summary>
        /// Ip
        /// </summary>
        /// <returns></returns>
		public IPAddress GetIPAddress()
        {
            return ((IPEndPoint)_worksocket.RemoteEndPoint).Address;
        }
        /// <summary>
        /// 接收消息
        /// </summary>
		private void AsynRecive()
        {
            if (_worksocket == null || _worksocket.Connected == false) return;
            _worksocket.BeginReceive(_msg.Data, _msg.StartIndex, _msg.RemainSize, SocketFlags.None, ReceiveCallback, null);
        }
        /// <summary>
        /// 接收消息的处理
        /// </summary>
        /// <param name="ar"></param>
		private void ReceiveCallback(IAsyncResult ar)
        {
            if (_worksocket == null || _worksocket.Connected == false) return;
            int count = 0;
            try
            {
                count = _worksocket.EndReceive(ar);//本次接收到的数据长度
            }
            catch
            {
                DisConnectedHandler();
                return;
            }

            if (count == 0)
            {
                DisConnectedHandler();
                return;
            }

            try
            {
                _msg.ParseFromServerMessage(count, ReceiveHandler);
            }
            catch (Exception e)
            {
                throw new Exception("解析服务器数据时发生错误", e);
            }
            AsynRecive();
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        public bool AsynSend(Request packet)
        {
            if (_worksocket == null || !_worksocket.Connected)
            {
                return false;
            }
            if (packet == null) return false;

            try
            {
                byte[] bytes = Message.ClientPackData(packet);
                _worksocket.Send(bytes);
                return true;
            }
            catch (Exception e)
            {
                throw new Exception("发送数据时报错",e);
            }
        }

        /// <summary>
        /// 连接断开 必须被子类重写
        /// </summary>
        public abstract void DisConnectedHandler();

        /// <summary>
        /// 接收数据处理 必须被子类重写
        /// </summary>
        /// <param name="response"></param>
        public abstract void ReceiveHandler(Response response);

        /// <summary>
        /// 关闭由Client调用
        /// </summary>
        public void Close()
        {
            if (_worksocket != null)
            {
                // _worksocket.Shutdown(SocketShutdown.Both);
                _worksocket.Close();
                _worksocket = null;
            }
        }

        /// <summary>
        /// 判断当前连接是否
        /// </summary>
        public bool IsConnected
        {
            get
            {
                if (_worksocket != null)
                    return _worksocket.Connected;
                return false;
            }
        }
    }
}
